package com.ruoyi.project.system.controller;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.framework.aspectj.lang.annotation.Anonymous;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.system.domain.SmPay;
import com.ruoyi.project.system.domain.SmProduct;
import com.ruoyi.project.system.domain.SmQuery;
import com.ruoyi.project.system.domain.vo.PayVo;
import com.ruoyi.project.system.domain.vo.TeamPayOrder;
import com.ruoyi.project.system.mapper.SmIncomeMapper;
import com.ruoyi.project.system.mapper.SmPayMapper;
import com.ruoyi.project.system.mapper.SmQueryMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.project.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import static com.ruoyi.common.constant.CacheConstants.UPGRADE_COST;

/**
 * 支付Controller
 */
@Slf4j
@RestController
@RequestMapping("/system/pay")
public class SmPayController extends BaseController {

    @Autowired
    private SmSMSService smSMSService;

    @Autowired
    private ISmPayService smPayService;

    @Autowired
    private ISmQueryService smQueryService;

    @Autowired
    private ISmProductService smProductService;

    @Autowired
    private ISmRefundService iSmRefundService;

    @Autowired
    private SmQueryMapper smQueryMapper;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SmPayMapper smPayMapper;

    @Autowired
    private SmIncomeMapper smIncomeMapper;

    @Autowired
    private RedisCache redisCache;

    @Anonymous
    @GetMapping("/state")
    public Map<String, Object> state(@NotNull Long id) {
        return smPayMapper.payState(id);
    }

    /**
     * 查询支付
     */
    @Anonymous
    @GetMapping("/queryPay")
    public AjaxResult queryPay(@NotNull Integer id, @NotBlank String payType) {
        // 1. 获取查询订单
        SmQuery smQuery = smQueryService.selectSmQueryById(id);
        smQuery.setRemark(payType);
        // 2. 构建支付订单
        return smQueryService.promotionQueryPay(smQuery);
    }

    /**
     * 用户身份升级支付
     */
    @GetMapping("/upgradePay")
    public AjaxResult upgradePay(@NotBlank String roleKey, @NotBlank String payType) {
        Long userId = SecurityUtils.getUserId();
        Map<String, String> map = userMapper.selectRoleInfoByUserId(userId);
        String oldRoleKey = map.get("roleKey");
        String oldRoleName = map.get("roleName");
        String pricing = redisCache.getCacheObject(UPGRADE_COST + oldRoleKey + "->" + roleKey).toString();
        if ("member".equals(roleKey)) {           // 1. —> 队员
            oldRoleName += "升级为队员付费";
        } else if ("captain".equals(roleKey)) {   // 2. —> 队长
            oldRoleName += "升级为队长付费";
        } else if ("region".equals(roleKey)) {    // 3. —> 区域队长
            oldRoleName += "升级为区域队长付费";
        }
        SmPay smPay = new SmPay(new BigDecimal(pricing), oldRoleName, userId, payType, oldRoleKey + "->" + roleKey);
        return smPayService.upgradePay(smPay);
    }

    /**
     * 新增查询进件与支付
     */
    @PreAuthorize("@ss.hasPermi('system:query:add')")
    @PostMapping("/addQueryPay")
    public AjaxResult addQueryPay(@RequestBody SmQuery smQuery) {
        // 1. 写入查询订单
        smQueryService.insertSmQuery(smQuery);
        return smQueryService.selfQueryPay(smQuery);
    }

    @Anonymous
    @GetMapping("/stateByOrderNo")
    public String stateByOrderNo(@NotBlank String orderNo) {
        return smPayMapper.queryPayStateByOrderNo(orderNo);
    }

    /**
     * 修改支付订单(回调)
     */
    @Anonymous
    @Transactional
    @GetMapping("/notify")
    public String notify(@RequestParam Map<String, String> map) {
        log.info("支付返回：" + map);
        if (map.isEmpty()) {
            return "err";
        }
        // 检证数据
        String str = map.get("state") + "1394150425178931200" + map.get("orderNo") + map.get("amount") + "086951d2cdb0b467c553b507d6f866db";       // 容易查
        String sign = Md5Utils.hash(str);
        if (!sign.equalsIgnoreCase(map.get("sign"))) {
            return "err";
        }   // MGZ TODO 2025/5/23: 支付回调
        String orderNo = map.get("orderNo");
        SmPay smPay = smPayMapper.selectPayByOrderNo(orderNo);
        if (smPay == null) {
            return "fail";
        }
        if ("SUCCESS".equals(smPay.getPayState())) {
            return "success";
        }
        if ("1".equals(map.get("state"))) {         //支付成功
            // 1. 修改订单支付状态信息
            int update = smPayService.updateSmPay(new SmPay(
                    smPay.getId(),
                    BigDecimal.valueOf(Float.valueOf(map.get("actualPayAmount"))),
                    map.get("platformOrderNo"),
                    "SUCCESS",
                    DateUtils.parseDate(map.get("payTime"))
            ));
            // 2. 短信通知
            SmQuery query = smQueryMapper.selectSmQueryById(smPay.getOutId());
            SmProduct smProduct = smProductService.selectSmProductById(query.getProductId());
            smSMSService.sendReport(query.getTel(), smProduct.getCode(), map.get("orderNo"));

            // 3. 修改收益订单状态
            smIncomeMapper.paySuccessSetIncome(orderNo);
            // 4. 修改用户身份
            if ("upgrade".equals(smPay.getType())) {
                smPayService.paySuccessUpgradeSetUser(smPay);
            }
            return update == 1 ? "success" : "fail";
        } else {
            return "fail";
        }
    }

    @GetMapping("/teamPayOrders")
    public TableDataInfo teamPayOrders(TeamPayOrder teamPayOrder) {
        teamPayOrder.setParentId(SecurityUtils.getUserId().intValue());
        startPage();
        List<TeamPayOrder> list = smQueryMapper.teamPayOrders(teamPayOrder);
        return getDataTable(list);
    }

    /**
     * 退款
     */
    @GetMapping("/refund")
    public AjaxResult refund(@NotNull Integer id, @NotNull BigDecimal amount) throws Exception {
        SmPay smPay = smPayService.selectSmPayById(id);
        if (smPay == null) {
            return error("支付订单不存在");
        }
        if (!"SUCCESS".equals(smPay.getPayState())) {
            return error("支付订单状态不支持退款！");
        }
        if (smPay.getPricing().compareTo(amount) < 0) {
            return error("退款金额不能大于支付金额！");
        }
        smPay.setPricing(amount);
        return iSmRefundService.insertSmRefund(smPay);
    }

    @Anonymous
    @GetMapping("/promotionParam")
    public AjaxResult promotionParam(@NotNull Integer id) {
        // 1. 写入查询订单
        SmQuery query = smQueryService.selectSmQueryById(id);
        Long userId = query.getUserId().longValue();
        AjaxResult result = new AjaxResult();
        Integer productId = query.getProductId();
        result.put("productId", productId);
        if (StringUtils.isNotEmpty(query.getName())) {
            result.put("name", "**" + query.getName().substring(1));
        }
        if (StringUtils.isNotEmpty(query.getCardNo())) {
            result.put("cardNo", "******" + query.getCardNo().substring(10));
        }
        BigDecimal price = smProductService.promotionPrice(
                userId,
                userMapper.queryRoleId(userId),
                smProductService.selectSmProductById(productId)
        );
        result.put("price", price.setScale(2, BigDecimal.ROUND_DOWN));
        return result;
    }

    @PreAuthorize("@ss.hasPermi('system:pay:query')")
    @GetMapping(value = "/listOrderNo")
    public AjaxResult listOrderNoByOutId(@NotNull Integer outId) {
        return success(smPayMapper.listOrderNoByOutId(outId));
    }

    /**
     * 查询支付列表
     */
    @PreAuthorize("@ss.hasPermi('system:pay:list')")
    @GetMapping("/list")
    public TableDataInfo list(PayVo payVo) {
        startPage();
        List<PayVo> list = smPayService.selectSmPayList(payVo);
        return getDataTable(list);
    }

    @GetMapping("/teamList")
    public TableDataInfo teamList(PayVo payVo) {
        payVo.setUserId(SecurityUtils.getUserId());
        startPage();
        List<PayVo> list = smPayMapper.selectTeamSmPayList(payVo);
        return getDataTable(list);
    }

    /**
     * 获取支付详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:pay:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Integer id) {
        return success(smPayService.selectSmPayById(id));
    }

    /**
     * 新增支付
     */
    @PreAuthorize("@ss.hasPermi('system:pay:add')")
    @Log(title = "支付", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SmPay smPay) {
        return toAjax(smPayService.insertSmPay(smPay));
    }

    /**
     * 修改支付
     */
    @PreAuthorize("@ss.hasPermi('system:pay:edit')")
    @Log(title = "支付", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SmPay smPay) {
        return toAjax(smPayService.updateSmPay(smPay));
    }

    /**
     * 删除支付
     */
    @PreAuthorize("@ss.hasPermi('system:pay:remove')")
    @Log(title = "支付", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Integer[] ids) {
        return toAjax(smPayService.deleteSmPayByIds(ids));
    }

}
